Skip to content

infra(cpb): add dedicated role provisioning and schema setup#124

Merged
SashkoMarchuk merged 9 commits intomainfrom
feature/cpb-dedicated-role
Apr 7, 2026
Merged

infra(cpb): add dedicated role provisioning and schema setup#124
SashkoMarchuk merged 9 commits intomainfrom
feature/cpb-dedicated-role

Conversation

@SashkoMarchuk
Copy link
Copy Markdown
Collaborator

@SashkoMarchuk SashkoMarchuk commented Apr 7, 2026

Summary

  • Replace temporal-based interim DB setup with a two-script architecture using a dedicated cpb_app role
  • scripts/cpb/create-role.sh (NEW): One-time provisioning using RDS master password — creates cpb_app role, cpb_bot database, transfers ownership from temporal if needed, grants all privileges
  • scripts/cpb/setup-db.sh (REWRITTEN): Repeatable schema setup connecting as cpb_app — applies init-schema.sql, verifies all 6 tables
  • sql/cpb/init-schema.sql (NEW): Complete 6-table schema for CPB Slack bot (cycles, opt_in_responses, pairings, pair_history, interactions, admin_reports)
  • Deletes old scripts/cpb-setup-db.sh that required temporal user with CREATEDB
  • Adds POSTGRES_PASSWORD_MASTER to .env.example (commented out, one-time use)

Operational Workflow

1. Set POSTGRES_PASSWORD_MASTER, POSTGRES_PASSWORD_CPB, CPB_POSTGRES_HOST
2. Run: ./scripts/cpb/create-role.sh    (creates role + database)
3. Run: ./scripts/cpb/setup-db.sh       (creates schema tables)
4. Remove POSTGRES_PASSWORD_MASTER from environment

Security

  • Master password required via :? — immediate fail if unset, no fallbacks
  • validate_pg_identifier() on all SQL identifiers (regex + length check)
  • Single-quote escaping + $$ rejection on passwords
  • set -eo pipefail + ON_ERROR_STOP=1 on both scripts
  • No passwords in log output

Test plan

  • Verify bash -n syntax check passes on both scripts
  • Run create-role.sh against RDS — role and database created
  • Run create-role.sh again — idempotent, no errors, password updated
  • Run setup-db.sh — all 6 tables created
  • Run setup-db.sh again — idempotent, no errors
  • Verify cpb_app owns cpb_bot database
  • Verify schema matches init-schema.sql (triggers, indexes, constraints)

Supersedes #123

Summary by CodeRabbit

Release Notes

  • Chores

    • Reorganized PostgreSQL provisioning process into separate one-time role creation and schema initialization steps for improved setup reliability.
    • Updated environment variable configuration documentation with new provisioning credentials placeholder.
  • New Features

    • Added comprehensive database schema with tables for cycle management, user opt-in tracking, pairing records, interaction history, and administrative reporting capabilities.

SashkoMarchuk and others added 9 commits April 6, 2026 23:43
…ple Bot

Replace the old setup script that required postgres admin access and CREATEROLE
with a version that uses temporal user (CREATEDB) and grants to existing n8n user.
Add complete 6-table schema (cycles, opt_in_responses, pairings, pair_history,
interactions, admin_reports) with idempotent IF NOT EXISTS, triggers, and indexes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix two filename references in header comments flagged by CodeRabbit:
- setup-db.sh usage example: cpb-setup-db.sh → cpb/setup-db.sh
- init-schema.sql usage example: cpb-init-schema.sql → init-schema.sql

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Refactor schema grant error handling from fragile `cmd && echo || { ... }`
to proper if/then/else. Prevents false error-path execution if echo fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace temporal-based DB setup with a two-script architecture:
- create-role.sh: one-time provisioning using RDS master password
  to create cpb_app role and cpb_bot database
- setup-db.sh: repeatable schema setup connecting as cpb_app

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add REASSIGN OWNED step in create-role.sh to transfer object ownership
  (tables, sequences, functions) after database ownership transfer
- Fail fast in setup-db.sh when table count != 6 (exit 1, not warning)
- Add UNIQUE(cycle_id, person_a_id, person_b_id) to pairings table
- Replace independent touchpoint/action CHECKs with composite constraint
  that enforces valid combinations (e.g. blocks opt_in + satisfied)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
One report per cycle is the correct invariant — enforce at DB level.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add updated_at + trigger to pairings table (6 mutable columns had
  no modification timestamp, breaking pattern of other mutable tables)
- Remove 3 redundant indexes whose leading columns are already covered
  by UNIQUE constraints (opt_in_responses, pairings, admin_reports)
- Fix misleading "-v" hint in setup-db.sh error message

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enforce YYYY-MM format via regex to prevent invalid values like
'2026-13' or 'foobar' from being inserted. Flagged independently
by two /ultra XL agents (D2-contrarian, V2-schema).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Capture and display the actual psql error on connection failure
instead of suppressing it. Operators now see the real diagnostic
(wrong password, host unreachable, DB missing) instead of generic
"Cannot connect" message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@SashkoMarchuk SashkoMarchuk requested a review from killev as a code owner April 7, 2026 04:17
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

Reorganized PostgreSQL provisioning workflow from a single monolithic script to a two-stage process: moved from cpb-setup-db.sh to separate create-role.sh (one-time RDS provisioning with master credentials) and setup-db.sh (schema initialization). Updated .env.example to reflect new script names and added POSTGRES_PASSWORD_MASTER placeholder. Added new init-schema.sql defining complete database schema with tables, triggers, and indexes.

Changes

Cohort / File(s) Summary
Environment Configuration
.env.example
Updated provisioning comment to reference new script names (create-role.sh, setup-db.sh); added commented-out POSTGRES_PASSWORD_MASTER variable for RDS master password during one-time provisioning.
PostgreSQL Provisioning
scripts/cpb-setup-db.sh, scripts/cpb/create-role.sh
Removed old monolithic provisioning script; added new create-role.sh handling one-time RDS provisioning with master credentials, role/database creation, ownership management, and privilege grants with validation and password escaping.
Schema Initialization
scripts/cpb/setup-db.sh, sql/cpb/init-schema.sql
Added new setup-db.sh for schema file execution and connectivity validation; added init-schema.sql defining six core tables (cycles, opt_in_responses, pairings, pair_history, interactions, admin_reports), auto-update triggers, and supporting indexes.

Sequence Diagram

sequenceDiagram
    participant Admin as Administrator
    participant CPBCreate as create-role.sh
    participant RDS as RDS PostgreSQL
    participant CPBSetup as setup-db.sh
    participant SchemaFile as init-schema.sql

    Admin->>CPBCreate: Run (POSTGRES_PASSWORD_MASTER)
    CPBCreate->>RDS: Connect with master credentials
    CPBCreate->>RDS: Create/update cpb_app role
    CPBCreate->>RDS: Create cpb_bot database
    CPBCreate->>RDS: Transfer ownership to cpb_app
    CPBCreate->>RDS: Reassign existing objects ownership
    CPBCreate->>RDS: Grant privileges to cpb_app
    RDS-->>CPBCreate: Provisioning complete
    
    Admin->>CPBSetup: Run (POSTGRES_PASSWORD_CPB)
    CPBSetup->>SchemaFile: Resolve schema file path
    CPBSetup->>RDS: Connect with cpb_app credentials
    CPBSetup->>RDS: Verify connectivity (SELECT 1)
    CPBSetup->>SchemaFile: Read and execute schema
    SchemaFile->>RDS: Create tables, triggers, indexes
    RDS-->>SchemaFile: Schema applied
    CPBSetup->>RDS: Verify 6 tables exist
    RDS-->>CPBSetup: Schema initialization complete
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

database

Suggested reviewers

  • killev

Poem

🐰 A rabbit hops through databases bright,
Where roles are created with master's might,
Then schemas bloom with tables galore,
Triggers and indexes forevermore—
Two stages of setup, now clean and right! 🌱

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'infra(cpb): add dedicated role provisioning and schema setup' accurately summarizes the main change: replacing temporal-based setup with dedicated role provisioning and schema initialization scripts.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/cpb-dedicated-role

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

CodeRabbit CodeRabbit

🤖 CodeRabbit AI Review Available

To request a code review from CodeRabbit AI, add [coderabbit-ai-review] to your PR title.

CodeRabbit will analyze your code and provide feedback on:

  • Logic and correctness
  • Security issues
  • Performance optimizations
  • Code quality and best practices
  • Error handling
  • Maintainability

Note: Reviews are only performed when [coderabbit-ai-review] is present in the PR title.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 7, 2026

@SashkoMarchuk
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
scripts/cpb/create-role.sh (1)

49-65: Validates all identifiers including master user.

Good that MASTER_USER is also validated since it's interpolated into SQL statements. The validation function is duplicated from setup-db.sh — consider extracting to a shared shell library if more CPB scripts are added in the future.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/cpb/create-role.sh` around lines 49 - 65, The script duplicates the
validate_pg_identifier function (used to validate MASTER_USER, CPB_USER, CPB_DB)
which is already in setup-db.sh; extract validate_pg_identifier into a shared
shell library (e.g., lib-db.sh) and source it from both scripts, then remove the
duplicate function from create-role.sh and keep the calls validate_pg_identifier
"$MASTER_USER" "POSTGRES_USER_MASTER", validate_pg_identifier "$CPB_USER"
"POSTGRES_USER_CPB", validate_pg_identifier "$CPB_DB" "POSTGRES_DB_CPB"
unchanged so identifier validation remains enforced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@scripts/cpb/create-role.sh`:
- Around line 49-65: The script duplicates the validate_pg_identifier function
(used to validate MASTER_USER, CPB_USER, CPB_DB) which is already in
setup-db.sh; extract validate_pg_identifier into a shared shell library (e.g.,
lib-db.sh) and source it from both scripts, then remove the duplicate function
from create-role.sh and keep the calls validate_pg_identifier "$MASTER_USER"
"POSTGRES_USER_MASTER", validate_pg_identifier "$CPB_USER" "POSTGRES_USER_CPB",
validate_pg_identifier "$CPB_DB" "POSTGRES_DB_CPB" unchanged so identifier
validation remains enforced.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 6945a2c6-5b67-4a4c-9970-430faf220295

📥 Commits

Reviewing files that changed from the base of the PR and between 404d9ed and 5424f1f.

📒 Files selected for processing (5)
  • .env.example
  • scripts/cpb-setup-db.sh
  • scripts/cpb/create-role.sh
  • scripts/cpb/setup-db.sh
  • sql/cpb/init-schema.sql
💤 Files with no reviewable changes (1)
  • scripts/cpb-setup-db.sh

@SashkoMarchuk SashkoMarchuk merged commit 9704bbc into main Apr 7, 2026
28 of 34 checks passed
@SashkoMarchuk SashkoMarchuk deleted the feature/cpb-dedicated-role branch April 7, 2026 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant